home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '87 / Source ƒ.sea / Source ƒ / emacs source ƒ / FILE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-28  |  17.4 KB  |  560 lines  |  [TEXT/MARC]

  1. /*
  2.  * The routines in this file
  3.  * handle the reading and writing of
  4.  * disk files. All of details about the
  5.  * reading and writing of the disk are
  6.  * in "fileio.c".
  7.  */
  8. #include        <stdio.h>
  9. #include    "estruct.h"
  10. #include        "edef.h"
  11.  
  12. /*
  13.  * Read a file into the current
  14.  * buffer. This is really easy; all you do it
  15.  * find the name of the file, and call the standard
  16.  * "read a file into the current buffer" code.
  17.  * Bound to "C-X C-R".
  18.  */
  19. fileread(f, n)
  20. {
  21.         register int    s;
  22.         char fname[NFILEN];
  23.  
  24.         if ((s=mlreply("Read file: ", fname, NFILEN)) != TRUE)
  25.                 return(s);
  26.         return(readin(fname, TRUE));
  27. }
  28.  
  29. /*
  30.  * Insert a file into the current
  31.  * buffer. This is really easy; all you do it
  32.  * find the name of the file, and call the standard
  33.  * "insert a file into the current buffer" code.
  34.  * Bound to "C-X C-I".
  35.  */
  36. insfile(f, n)
  37. {
  38.         register int    s;
  39.         char fname[NFILEN];
  40.  
  41.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  42.         return(rdonly());    /* we are in read only mode    */
  43.         if ((s=mlreply("Insert file: ", fname, NFILEN)) != TRUE)
  44.                 return(s);
  45.         return(ifile(fname));
  46. }
  47.  
  48. /*
  49.  * Select a file for editing.
  50.  * Look around to see if you can find the
  51.  * fine in another buffer; if you can find it
  52.  * just switch to the buffer. If you cannot find
  53.  * the file, create a new buffer, read in the
  54.  * text, and switch to the new buffer.
  55.  * Bound to C-X C-F.
  56.  */
  57. filefind(f, n)
  58. {
  59.         char fname[NFILEN];    /* file user wishes to find */
  60.         register int s;        /* status return */
  61.  
  62.         if ((s=mlreply("Find file: ", fname, NFILEN)) != TRUE)
  63.                 return(s);
  64.     return(getfile(fname, TRUE));
  65. }
  66.  
  67. viewfile(f, n)    /* visit a file in VIEW mode */
  68. {
  69.         char fname[NFILEN];    /* file user wishes to find */
  70.         register int s;        /* status return */
  71.     register WINDOW *wp;    /* scan for windows that need updating */
  72.  
  73.         if ((s=mlreply("View file: ", fname, NFILEN)) != TRUE)
  74.                 return (s);
  75.     s = getfile(fname, FALSE);
  76.     if (s) {    /* if we succeed, put it in view mode */
  77.         curwp->w_bufp->b_mode |= MDVIEW;
  78.  
  79.         /* scan through and update mode lines of all windows */
  80.         wp = wheadp;
  81.         while (wp != NULL) {
  82.             wp->w_flag |= WFMODE;
  83.             wp = wp->w_wndp;
  84.         }
  85.     }
  86.     return(s);
  87. }
  88.  
  89. #if    CRYPT
  90. resetkey()    /* reset the encryption key if needed */
  91.  
  92. {
  93.     register int s;    /* return status */
  94.  
  95.     /* turn off the encryption flag */
  96.     cryptflag = FALSE;
  97.  
  98.     /* if we are in crypt mode */
  99.     if (curbp->b_mode & MDCRYPT) {
  100.         if (curbp->b_key[0] == 0) {
  101.             s = setkey(FALSE, 0);
  102.             if (s != TRUE)
  103.                 return(s);
  104.         }
  105.  
  106.         /* let others know... */
  107.         cryptflag = TRUE;
  108.  
  109.         /* and set up the key to be used! */
  110.         /* de-encrypt it */
  111.         crypt((char *)NULL, 0);
  112.         crypt(curbp->b_key, strlen(curbp->b_key));
  113.  
  114.         /* re-encrypt it...seeding it to start */
  115.         crypt((char *)NULL, 0);
  116.         crypt(curbp->b_key, strlen(curbp->b_key));
  117.     }
  118.  
  119.     return(TRUE);
  120. }
  121. #endif
  122.  
  123. getfile(fname, lockfl)
  124.  
  125. char fname[];        /* file name to find */
  126. int lockfl;        /* check the file for locks? */
  127.  
  128. {
  129.         register BUFFER *bp;
  130.         register LINE   *lp;
  131.         register int    i;
  132.         register int    s;
  133.         char bname[NBUFN];    /* buffer name to put file */
  134.  
  135.         for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
  136.                 if ((bp->b_flag&BFINVS)==0 && strcmp(bp->b_fname, fname)==0) {
  137.             swbuffer(bp);
  138.                         lp = curwp->w_dotp;
  139.                         i = curwp->w_ntrows/2;
  140.                         while (i-- && lback(lp)!=curbp->b_linep)
  141.                                 lp = lback(lp);
  142.                         curwp->w_linep = lp;
  143.                         curwp->w_flag |= WFMODE|WFHARD;
  144.                         mlwrite("[Old buffer]");
  145.                         return (TRUE);
  146.                 }
  147.         }
  148.         makename(bname, fname);                 /* New buffer name.     */
  149.         while ((bp=bfind(bname, FALSE, 0)) != NULL) {
  150.                 s = mlreply("Buffer name: ", bname, NBUFN);
  151.                 if (s == ABORT)                 /* ^G to just quit      */
  152.                         return (s);
  153.                 if (s == FALSE) {               /* CR to clobber it     */
  154.                         makename(bname, fname);
  155.                         break;
  156.                 }
  157.         }
  158.         if (bp==NULL && (bp=bfind(bname, TRUE, 0))==NULL) {
  159.                 mlwrite("Cannot create buffer");
  160.                 return (FALSE);
  161.         }
  162.         if (--curbp->b_nwnd == 0) {             /* Undisplay.           */
  163.                 curbp->b_dotp = curwp->w_dotp;
  164.                 curbp->b_doto = curwp->w_doto;
  165.                 curbp->b_markp = curwp->w_markp;
  166.                 curbp->b_marko = curwp->w_marko;
  167.         }
  168.         curbp = bp;                             /* Switch to it.        */
  169.         curwp->w_bufp = bp;
  170.         curbp->b_nwnd++;
  171.         return(readin(fname, lockfl));          /* Read it in.          */
  172. }
  173.  
  174. /*
  175.  * Read file "fname" into the current
  176.  * buffer, blowing away any text found there. Called
  177.  * by both the read and find commands. Return the final
  178.  * status of the read. Also called by the mainline,
  179.  * to read in a file specified on the command line as
  180.  * an argument. If the filename ends in a ".c", CMODE is
  181.  * set for the current buffer.
  182.  */
  183. readin(fname, lockfl)
  184.  
  185. char    fname[];    /* name of file to read */
  186. int    lockfl;        /* check for file locks? */
  187.  
  188. {
  189.         register LINE   *lp1;
  190.         register LINE   *lp2;
  191.         register int    i;
  192.         register WINDOW *wp;
  193.         register BUFFER *bp;
  194.         register int    s;
  195.         register int    nbytes;
  196.         register int    nline;
  197.     register char    *sptr;        /* pointer into filename string */
  198.     int        lflag;        /* any lines longer than allowed? */
  199.         char            line[NLINE];
  200.  
  201. #if    FILOCK
  202.     if (lockfl && lockchk(fname) == ABORT)
  203.         return(ABORT);
  204. #endif
  205. #if    CRYPT
  206.     s = resetkey();
  207.     if (s != TRUE)
  208.         return(s);
  209. #endif
  210.         bp = curbp;                             /* Cheap.               */
  211.         if ((s=bclear(bp)) != TRUE)             /* Might be old.        */
  212.                 return (s);
  213.         bp->b_flag &= ~(BFINVS|BFCHG);
  214. #if    ACMODE
  215.     if (strlen(fname) > 1) {        /* check if a 'C' file    */
  216.         sptr = fname + strlen(fname) - 2;
  217.         if (*sptr == '.' &&
  218.            (*(sptr + 1) == 'c' || *(sptr + 1) == 'h'))
  219.             bp->b_mode |= MDCMOD;
  220.     }
  221. #endif
  222.         strcpy(bp->b_fname, fname);
  223.  
  224.     /* turn off ALL keyboard translation in case we get a dos error */
  225.     (*term.t_kclose)();
  226.  
  227.         if ((s=ffropen(fname)) == FIOERR)       /* Hard file open.      */
  228.                 goto out;
  229.         if (s == FIOFNF) {                      /* File not found.      */
  230.                 mlwrite("[New file]");
  231.                 goto out;
  232.         }
  233.         mlwrite("[Reading file]");
  234.         nline = 0;
  235.     lflag = FALSE;
  236.         while ((s=ffgetline(line, NLINE)) == FIOSUC || s == FIOLNG) {
  237.         if (s == FIOLNG)
  238.             lflag = TRUE;
  239.                 nbytes = strlen(line);
  240.                 if ((lp1=lalloc(nbytes)) == NULL) {
  241.                         s = FIOERR;             /* Keep message on the  */
  242.                         break;                  /* display.             */
  243.                 }
  244.                 lp2 = lback(curbp->b_linep);
  245.                 lp2->l_fp = lp1;
  246.                 lp1->l_fp = curbp->b_linep;
  247.                 lp1->l_bp = lp2;
  248.                 curbp->b_linep->l_bp = lp1;
  249.                 for (i=0; i<nbytes; ++i)
  250.                         lputc(lp1, i, line[i]);
  251.                 ++nline;
  252.         }
  253.         ffclose();                              /* Ignore errors.       */
  254.         if (s == FIOEOF) {                      /* Don't zap message!   */
  255.                 if (nline == 1)
  256.                         mlwrite("[Read 1 line]");
  257.                 else
  258.                         mlwrite("[Read %d lines]", nline);
  259.         }
  260.     if (lflag)
  261.         mlwrite("[Read %d line(s), Long lines wrapped]",nline);
  262. out:
  263.     (*term.t_kopen)();    /* open the keyboard again */
  264.         for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  265.                 if (wp->w_bufp == curbp) {
  266.                         wp->w_linep = lforw(curbp->b_linep);
  267.                         wp->w_dotp  = lforw(curbp->b_linep);
  268.                         wp->w_doto  = 0;
  269.                         wp->w_markp = NULL;
  270.                         wp->w_marko = 0;
  271.                         wp->w_flag |= WFMODE|WFHARD;
  272.                 }
  273.         }
  274.         if (s == FIOERR || s == FIOFNF)        /* False if error.      */
  275.                 return(FALSE);
  276.         return (TRUE);
  277. }
  278.  
  279. /*
  280.  * Take a file name, and from it
  281.  * fabricate a buffer name. This routine knows
  282.  * about the syntax of file names on the target system.
  283.  * I suppose that this information could be put in
  284.  * a better place than a line of code.
  285.  */
  286. makename(bname, fname)
  287. char    bname[];
  288. char    fname[];
  289. {
  290.         register char   *cp1;
  291.         register char   *cp2;
  292.  
  293.         cp1 = &fname[0];
  294.         while (*cp1 != 0)
  295.                 ++cp1;
  296.  
  297. #if     AMIGA
  298.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='/')
  299.                 --cp1;
  300. #endif
  301. #if     VMS
  302.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!=']')
  303.                 --cp1;
  304. #endif
  305. #if     CPM
  306.         while (cp1!=&fname[0] && cp1[-1]!=':')
  307.                 --cp1;
  308. #endif
  309. #if     MSDOS
  310.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\'&&cp1[-1]!='/')
  311.                 --cp1;
  312. #endif
  313. #if     V7 | USG | BSD
  314.         while (cp1!=&fname[0] && cp1[-1]!='/')
  315.                 --cp1;
  316. #endif
  317.         cp2 = &bname[0];
  318.         while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=';')
  319.                 *cp2++ = *cp1++;
  320.         *cp2 = 0;
  321. }
  322.  
  323. /*
  324.  * Ask for a file name, and write the
  325.  * contents of the current buffer to that file.
  326.  * Update the remembered file name and clear the
  327.  * buffer changed flag. This handling of file names
  328.  * is different from the earlier versions, and
  329.  * is more compatable with Gosling EMACS than
  330.  * with ITS EMACS. Bound to "C-X C-W".
  331.  */
  332. filewrite(f, n)
  333. {
  334.         register WINDOW *wp;
  335.         register int    s;
  336.         char            fname[NFILEN];
  337.  
  338.         if ((s=mlreply("Write file: ", fname, NFILEN)) != TRUE)
  339.                 return (s);
  340.         if ((s=writeout(fname)) == TRUE) {
  341.                 strcpy(curbp->b_fname, fname);
  342.                 curbp->b_flag &= ~BFCHG;
  343.                 wp = wheadp;                    /* Update mode lines.   */
  344.                 while (wp != NULL) {
  345.                         if (wp->w_bufp == curbp)
  346.                                 wp->w_flag |= WFMODE;
  347.                         wp = wp->w_wndp;
  348.                 }
  349.         }
  350.         return (s);
  351. }
  352.  
  353. /*
  354.  * Save the contents of the current
  355.  * buffer in its associatd file. No nothing
  356.  * if nothing has changed (this may be a bug, not a
  357.  * feature). Error if there is no remembered file
  358.  * name for the buffer. Bound to "C-X C-S". May
  359.  * get called by "C-Z".
  360.  */
  361. filesave(f, n)
  362. {
  363.         register WINDOW *wp;
  364.         register int    s;
  365.  
  366.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  367.         return(rdonly());    /* we are in read only mode    */
  368.         if ((curbp->b_flag&BFCHG) == 0)         /* Return, no changes.  */
  369.                 return (TRUE);
  370.         if (curbp->b_fname[0] == 0) {           /* Must have a name.    */
  371.                 mlwrite("No file name");
  372.                 return (FALSE);
  373.         }
  374.         if ((s=writeout(curbp->b_fname)) == TRUE) {
  375.                 curbp->b_flag &= ~BFCHG;
  376.                 wp = wheadp;                    /* Update mode lines.   */
  377.                 while (wp != NULL) {
  378.                         if (wp->w_bufp == curbp)
  379.                                 wp->w_flag |= WFMODE;
  380.                         wp = wp->w_wndp;
  381.                 }
  382.         }
  383.         return (s);
  384. }
  385.  
  386. /*
  387.  * This function performs the details of file
  388.  * writing. Uses the file management routines in the
  389.  * "fileio.c" package. The number of lines written is
  390.  * displayed. Sadly, it looks inside a LINE; provide
  391.  * a macro for this. Most of the grief is error
  392.  * checking of some sort.
  393.  */
  394. writeout(fn)
  395. char    *fn;
  396. {
  397.         register int    s;
  398.         register LINE   *lp;
  399.         register int    nline;
  400.  
  401. #if    CRYPT
  402.     s = resetkey();
  403.     if (s != TRUE)
  404.         return(s);
  405. #endif
  406.     /* turn off ALL keyboard translation in case we get a dos error */
  407.     (*term.t_kclose)();
  408.  
  409.         if ((s=ffwopen(fn)) != FIOSUC) {        /* Open writes message. */
  410.         (*term.t_kopen)();
  411.                 return (FALSE);
  412.         }
  413.     mlwrite("[Writing..]");            /* tell us were writing */
  414.         lp = lforw(curbp->b_linep);             /* First line.          */
  415.         nline = 0;                              /* Number of lines.     */
  416.         while (lp != curbp->b_linep) {
  417.                 if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
  418.                         break;
  419.                 ++nline;
  420.                 lp = lforw(lp);
  421.         }
  422.         if (s == FIOSUC) {                      /* No write error.      */
  423.                 s = ffclose();
  424.                 if (s == FIOSUC) {              /* No close error.      */
  425.                         if (nline == 1)
  426.                                 mlwrite("[Wrote 1 line]");
  427.                         else
  428.                                 mlwrite("[Wrote %d lines]", nline);
  429.                 }
  430.         } else                                  /* Ignore close error   */
  431.                 ffclose();                      /* if a write error.    */
  432.     (*term.t_kopen)();
  433.         if (s != FIOSUC)                        /* Some sort of error.  */
  434.                 return (FALSE);
  435.         return (TRUE);
  436. }
  437.  
  438. /*
  439.  * The command allows the user
  440.  * to modify the file name associated with
  441.  * the current buffer. It is like the "f" command
  442.  * in UNIX "ed". The operation is simple; just zap
  443.  * the name in the BUFFER structure, and mark the windows
  444.  * as needing an update. You can type a blank line at the
  445.  * prompt if you wish.
  446.  */
  447. filename(f, n)
  448. {
  449.         register WINDOW *wp;
  450.         register int    s;
  451.         char            fname[NFILEN];
  452.  
  453.         if ((s=mlreply("Name: ", fname, NFILEN)) == ABORT)
  454.                 return (s);
  455.         if (s == FALSE)
  456.                 strcpy(curbp->b_fname, "");
  457.         else
  458.                 strcpy(curbp->b_fname, fname);
  459.         wp = wheadp;                            /* Update mode lines.   */
  460.         while (wp != NULL) {
  461.                 if (wp->w_bufp == curbp)
  462.                         wp->w_flag |= WFMODE;
  463.                 wp = wp->w_wndp;
  464.         }
  465.     curbp->b_mode &= ~MDVIEW;    /* no longer read only mode */
  466.         return (TRUE);
  467. }
  468.  
  469. /*
  470.  * Insert file "fname" into the current
  471.  * buffer, Called by insert file command. Return the final
  472.  * status of the read.
  473.  */
  474. ifile(fname)
  475. char    fname[];
  476. {
  477.         register LINE   *lp0;
  478.         register LINE   *lp1;
  479.         register LINE   *lp2;
  480.         register int    i;
  481.         register BUFFER *bp;
  482.         register int    s;
  483.         register int    nbytes;
  484.         register int    nline;
  485.     int        lflag;        /* any lines longer than allowed? */
  486.         char            line[NLINE];
  487.  
  488.         bp = curbp;                             /* Cheap.               */
  489.         bp->b_flag |= BFCHG;            /* we have changed    */
  490.     bp->b_flag &= ~BFINVS;            /* and are not temporary*/
  491.         if ((s=ffropen(fname)) == FIOERR)       /* Hard file open.      */
  492.                 goto out;
  493.         if (s == FIOFNF) {                      /* File not found.      */
  494.                 mlwrite("[No such file]");
  495.         return(FALSE);
  496.         }
  497.         mlwrite("[Inserting file]");
  498.  
  499. #if    CRYPT
  500.     s = resetkey();
  501.     if (s != TRUE)
  502.         return(s);
  503. #endif
  504.     /* back up a line and save the mark here */
  505.     curwp->w_dotp = lback(curwp->w_dotp);
  506.     curwp->w_doto = 0;
  507.     curwp->w_markp = curwp->w_dotp;
  508.     curwp->w_marko = 0;
  509.  
  510.         nline = 0;
  511.     lflag = FALSE;
  512.         while ((s=ffgetline(line, NLINE)) == FIOSUC || s == FIOLNG) {
  513.         if (s == FIOLNG)
  514.             lflag = TRUE;
  515.                 nbytes = strlen(line);
  516.                 if ((lp1=lalloc(nbytes)) == NULL) {
  517.                         s = FIOERR;             /* Keep message on the  */
  518.                         break;                  /* display.             */
  519.                 }
  520.         lp0 = curwp->w_dotp;    /* line previous to insert */
  521.         lp2 = lp0->l_fp;    /* line after insert */
  522.  
  523.         /* re-link new line between lp0 and lp2 */
  524.         lp2->l_bp = lp1;
  525.         lp0->l_fp = lp1;
  526.         lp1->l_bp = lp0;
  527.         lp1->l_fp = lp2;
  528.  
  529.         /* and advance and write out the current line */
  530.         curwp->w_dotp = lp1;
  531.                 for (i=0; i<nbytes; ++i)
  532.                         lputc(lp1, i, line[i]);
  533.                 ++nline;
  534.         }
  535.         ffclose();                              /* Ignore errors.       */
  536.     curwp->w_markp = lforw(curwp->w_markp);
  537.         if (s == FIOEOF) {                      /* Don't zap message!   */
  538.                 if (nline == 1)
  539.                         mlwrite("[Inserted 1 line]");
  540.                 else
  541.                         mlwrite("[Inserted %d lines]", nline);
  542.         }
  543.     if (lflag)
  544.         mlwrite("[Inserted %d line(s), Long lines wrapped]",nline);
  545. out:
  546.     /* advance to the next line and mark the window for changes */
  547.     curwp->w_dotp = lforw(curwp->w_dotp);
  548.     curwp->w_flag |= WFHARD | WFMODE;
  549.  
  550.     /* copy window parameters back to the buffer structure */
  551.     curbp->b_dotp = curwp->w_dotp;
  552.     curbp->b_doto = curwp->w_doto;
  553.     curbp->b_markp = curwp->w_markp;
  554.     curbp->b_marko = curwp->w_marko;
  555.  
  556.         if (s == FIOERR)                        /* False if error.      */
  557.                 return (FALSE);
  558.         return (TRUE);
  559. }
  560.